/**
 * 数据库连接池配置模块
 * 
 * 主要功能：
 * 1. 创建MySQL连接池
 * 2. 测试数据库连接
 * 3. 导出连接池供其他模块使用
 * 
 * 连接池的优点：
 * - 复用连接：避免频繁创建和关闭连接的开销
 * - 并发控制：限制同时连接数，防止数据库过载
 * - 自动管理：自动处理连接的创建、分配、释放
 * 
 * @author 个人预算管理系统开发团队
 * @date 2025-10-26
 */

// ==================== 依赖导入 ====================
/**
 * mysql2/promise
 * MySQL客户端库（Promise版本）
 * 
 * 为什么使用mysql2：
 * 1. 支持Promise，可以使用async/await
 * 2. 性能比mysql库更好
 * 3. 支持预处理语句（防止SQL注入）
 * 4. 向后兼容mysql库
 */
const mysql = require('mysql2/promise');

// ==================== 连接池配置 ====================

/**
 * MySQL连接池实例
 * 
 * 配置参数说明：
 * @property {string} host - 数据库服务器地址
 * @property {string} user - 数据库用户名
 * @property {string} password - 数据库密码
 * @property {string} database - 数据库名称
 * @property {number} port - 数据库端口（MySQL默认3306）
 * @property {boolean} waitForConnections - 连接池耗尽时是否等待（true: 等待，false: 返回错误）
 * @property {number} connectionLimit - 连接池最大连接数
 * @property {number} queueLimit - 排队等待连接的请求数限制（0表示无限制）
 * @property {string} charset - 字符集（utf8mb4支持emoji和特殊字符）
 * 
 * 设计思路：
 * 1. 所有配置都从环境变量读取，便于部署到不同环境
 * 2. 提供默认值，方便本地开发
 * 3. 连接限制为10，适合中小型应用（可根据需求调整）
 * 4. waitForConnections=true：并发高时排队等待，而不是直接失败
 * 5. queueLimit=0：不限制排队数量，但可能导致内存问题（大流量时建议设置限制）
 * 
 * 环境变量配置（.env文件）：
 * DB_HOST=localhost
 * DB_USER=root
 * DB_PASSWORD=your_password
 * DB_NAME=budget_system
 * DB_PORT=3306
 */
const pool = mysql.createPool({
    host: process.env.DB_HOST || 'localhost',      // 数据库主机地址
    user: process.env.DB_USER || 'root',           // 数据库用户名
    password: process.env.DB_PASSWORD || '',       // 数据库密码
    database: process.env.DB_NAME || 'budget_system', // 数据库名称
    port: process.env.DB_PORT || 3306,             // 数据库端口
    waitForConnections: true,                       // 连接池耗尽时等待
    connectionLimit: 10,                            // 最多10个并发连接
    queueLimit: 0,                                  // 队列无限制
    charset: 'utf8mb4'                              // UTF-8字符集（支持emoji）
});

// ==================== 连接测试 ====================

/**
 * 测试数据库连接
 * 
 * @description 在模块加载时立即测试数据库连接是否正常
 * 
 * 工作流程：
 * 1. 从连接池获取一个连接
 * 2. 如果成功，输出成功信息并释放连接
 * 3. 如果失败，输出错误信息（但不中断程序）
 * 
 * 设计思路：
 * 1. 在服务器启动时就发现数据库问题，而不是等到第一次查询时
 * 2. 使用Promise链式调用，代码简洁
 * 3. 即使连接失败也不退出程序，让开发者有机会修复配置
 * 4. 释放连接很重要，避免占用连接池资源
 * 
 * 常见错误：
 * - ER_ACCESS_DENIED_ERROR：用户名或密码错误
 * - ER_BAD_DB_ERROR：数据库不存在
 * - ECONNREFUSED：MySQL服务未启动或地址错误
 */
pool.getConnection()
    .then(connection => {
        // 连接成功
        console.log('✅ 数据库连接成功');
        
        // 释放连接回连接池
        // 非常重要：必须释放连接，否则连接池会被耗尽
        connection.release();
    })
    .catch(err => {
        // 连接失败
        console.error('❌ 数据库连接失败:', err.message);
        
        // 输出详细错误信息（仅在开发环境）
        if (process.env.NODE_ENV === 'development') {
            console.error('详细错误:', err);
        }
        
        // 提示开发者检查配置
        console.error('请检查.env文件中的数据库配置');
    });

// ==================== 导出连接池 ====================

/**
 * 导出连接池实例
 * 
 * @exports pool - MySQL连接池
 * 
 * 使用示例：
 * const db = require('./config/database');
 * 
 * // 方式1：使用pool.query()（推荐）
 * const [rows] = await db.query('SELECT * FROM users WHERE user_id = ?', [1]);
 * 
 * // 方式2：手动获取连接（需要手动释放）
 * const connection = await db.getConnection();
 * try {
 *   const [rows] = await connection.query('SELECT * FROM users');
 *   // ... 处理数据
 * } finally {
 *   connection.release(); // 必须释放！
 * }
 * 
 * 注意事项：
 * 1. 推荐使用pool.query()，自动管理连接
 * 2. 如果使用getConnection()，必须在finally中释放连接
 * 3. 使用?占位符进行参数化查询，防止SQL注入
 * 4. query()返回[rows, fields]数组，通常只需要rows
 */
module.exports = pool; 